// 功能:初始化dram控制器(dramc)

#include "common.h"

#define P1MEMSTAT	0x7E001000
#define P1MEMCCMD	0x7E001004
#define P1DIRECTCMD	0x7E001008
#define P1MEMCFG	0x7E00100C
#define P1REFRESH	0x7E001010
#define P1CASLAT	0x7E001014
#define P1T_DQSS	0x7E001018
#define	P1T_MRD		0x7E00101C
#define	P1T_RAS		0x7E001020
#define P1T_RC		0x7E001024
#define P1T_RCD		0x7E001028
#define P1T_RFC		0x7E00102C
#define P1T_RP		0x7E001030
#define	P1T_RRD		0x7E001034
#define P1T_WR		0x7E001038
#define P1T_WTR		0x7E00103C
#define P1T_XP		0x7E001040
#define P1T_XSR		0x7E001044
#define P1T_ESR		0x7E001048
#define P1MEMCFG2	0x7E00104C
#define P1MEMCFG3	0x7E001050

#define P1_chip_0_cfg	0x7E001200
#define P1_chip_1_cfg	0x7E001204

#define P1_id_0_cfg		0x7E001100
#define P1_id_1_cfg		0x7E001104
#define P1_id_2_cfg		0x7E001108
#define P1_id_3_cfg		0x7E00110C
#define P1_id_4_cfg		0x7E001110
#define P1_id_5_cfg		0x7E001114
#define P1_id_6_cfg		0x7E001118
#define P1_id_7_cfg		0x7E00111C
#define P1_id_8_cfg		0x7E001120
#define P1_id_9_cfg		0x7E001124
#define P1_id_10_cfg	0x7E001128
#define P1_id_11_cfg	0x7E00112C
#define P1_id_12_cfg	0x7E001130
#define P1_id_13_cfg	0x7E001134
#define P1_id_14_cfg	0x7E001138
#define P1_id_15_cfg	0x7E00113C


#define MEM_SYS_CFG		0x7E00F120

#define MCLK 133000000

#define nstoclk(ns) (ns/(1000000000/MCLK)+1)

/* 根据6410手册P192页相关步骤和sdram手册来初始化dram控制器(dramc) */
int sdram_init(void)
{
	/* 1.使dramc进入"config"状态 */
	set_val(P1MEMCCMD, 0x04);

	/* 2.设置timing parameter, chip configuration, id configuration registers */
	/* 2.1 刷新周期 */
	set_val(P1REFRESH, nstoclk(7800));		//刷新周期:(7.8us)/((1/HCLK)s)=(7.8*10^3)/(1/133*10^6)
	/* 2.2 时间参数,下列设置全都是取了最小值 */
	set_val(P1CASLAT, (0x03<<1));			//CAS Latency:指的是内存存取数据所需的延迟时间,简单的说,就是内存接到CPU的指令后的反应速度。一般的参数值是2和3两种。K4X1G163PQ的芯片手册上CAS Latency=3

	set_val(P1T_DQSS, 0x01);				//下列设置均在sdram手册中可查询到
	set_val(P1T_MRD, 0x02);
	set_val(P1T_RAS, nstoclk(45));
	set_val(P1T_RC, nstoclk(68));

	u32 trcd = nstoclk(23);
	set_val(P1T_RCD, trcd | ((trcd-3)<<3));
	u32 trfc = nstoclk(80);
	set_val(P1T_RFC, trfc | ((trfc-3)<<5));
	u32 trp = nstoclk(23);
	set_val(P1T_RP, trp | ((trp-3)<<3));
	set_val(P1T_RRD, nstoclk(15));
	set_val(P1T_WR, nstoclk(15));
	//set_val(P1T_MRD, nstoclk(15));

	set_val(P1T_WTR, 0x01);
	set_val(P1T_XP, 0x02);
	set_val(P1T_XSR, nstoclk(120));
	set_val(P1T_ESR, nstoclk(120));

	/* 2.3 chip configuration */
	set_nbit(P1MEMCFG, 0, 3, 0x02);			// column address(10):A0~A9
	set_nbit(P1MEMCFG, 3, 3, 0x03);			// row address(14):A0~A13
	set_zero(P1MEMCFG, 6);					// A10/AP
	set_nbit(P1MEMCFG, 15, 3, 0x02);		// Burst Length (2,4,8,16)
	set_nbit(P1MEMCFG2, 0, 4, 0x05);
	set_2bit(P1MEMCFG2, 6, 0x01);			// 32 bit
	set_nbit(P1MEMCFG2, 8, 3, 0x03);		// Mobile DDR SDRAM
	set_2bit(P1MEMCFG2, 11, 0x01);
	set_one(P1_chip_0_cfg, 16);				// Bank-Row-Column organization

	/* 3.初始化sdram */
	set_val(P1DIRECTCMD, 0x0C0000);			// NOP
	set_val(P1DIRECTCMD, 0x00);				// precharge
	set_val(P1DIRECTCMD, 0x040000);			// auto refresh
	set_val(P1DIRECTCMD, 0x040000);			// auto refresh
	set_val(P1DIRECTCMD, 0x0A0000);			// EMRS
	set_val(P1DIRECTCMD, 0x080032);			// MRS
	
	set_val(MEM_SYS_CFG, 0x00);

	/* 4.使dramc进入"ready"状态 */
	set_val(P1MEMCCMD, 0x00);

	while(!((read_val(P1MEMSTAT)&0x03)==0x01));		//等待dramc进入"ready"状态
}


